<?php

namespace App\Third\Service\Sms;


use App\Common\Constants\ErrorCode;
use App\Common\Service\BaseService;
use Hyperf\Guzzle\ClientFactory;

/**
 * http://121.43.104.172:8040/msm/江苏迅辰信息科技有限公司提供服务
 * Class SmsService
 * @package App\Third\Service\Sms
 */
class SmsService extends  BaseService
{
    protected $sms_redirect_uri;
    protected $sms_username;
    protected $sms_password;
    protected $sms_verycode;
    protected $sms_tempid;
    /**
     * http Client
     * @var
     */
    protected $httpClient;

    /**
     * @var \Hyperf\Guzzle\ClientFactory
     */
    private $clientFactory;

    public function __construct(ClientFactory $clientFactory)
    {
        parent::__construct();
        $this->sms_redirect_uri = env('SMS_REDIRECT_URI', 'http://121.43.104.172:8030/service/httpService/httpInterface.do');
        $this->sms_username = env('SMS_USERNAME', 'XC10263');
        $this->sms_password = env('SMS_PASSWORD', '2955y416');
        $this->sms_verycode = env('SMS_VERYCODE', 'h2qh59xjqubj');
        $this->sms_tempid = env('SMS_TEMPID', 'XC10263-0004');
        $this->clientFactory = $clientFactory;
        $options = ['headers' => ['Content-Type' => 'application/json'], 'timeout' => 30.0];
        $this -> httpClient = $this->clientFactory->create($options);
    }

    /**
     * 验证码发送
     * @param $mobile
     * @param $code
     * @param null $tempid
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function send($mobile, $code, $tempid = null)
    {
        $data = [
            'method' => 'sendMsg',
            'username' => $this->sms_username,
            'password' => $this->sms_password,
            'mobile' => $mobile,
            'content' => "@1@=" . $code,
            'veryCode' => $this->sms_verycode,
            'msgtype' => "2",
            'tempid' => $tempid ?? $this->sms_tempid,
            'code' => "utf-8"
        ];
        $headers = [
            'Content-Type: application/x-www-form-urlencoded',
        ];
        $options = [
            'headers' => $headers,
            'form_params' => $data
        ];
        $res = $this->httpClient->post($this->sms_redirect_uri,$options);
        $resXml = $res->getBody()->getContents();
        $callBack = $this->xml_to_array($resXml);
        if ($callBack['sms']['mt']['status'] == 0 and is_null($tempid)) {
            // 成功，存入缓存
            $this->smsRedis->set('sms-' . $mobile, $code, 300);
            return ['code' => ErrorCode::SUCCESS, 'data' => []];
        } else {
            // 发送失败
            return ['code' => ErrorCode::NOT_IN_FORCE];
        }
    }

    /**
     * 发送短信
     * @param $mobile
     * @param $content
     * @param $temp_id
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sendOut($mobile, $content, $temp_id)
    {
        $result = $this->httpClient->post($this->sms_redirect_uri, [
            'headers'     => [
                'Content-Type: application/x-www-form-urlencoded',
            ],
            'form_params' => [
                'method'   => 'sendMsg',
                'username' => $this->sms_username,
                'password' => $this->sms_password,
                'mobile'   => $mobile,
                'content'  => $content,
                'veryCode' => $this->sms_verycode,
                'msgtype'  => "2",
                'tempid'   => $temp_id,
                'code'     => "utf-8",
            ],
        ])->getBody()->getContents();
        $result = $this->xml_to_array($result);
        if ($result['sms']['mt']['status'] == 0) {
            return true;
        }
        return false;
    }
    private function xml_to_array($xml)
    {
        $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*)<\\/\\1>/";
        if (preg_match_all($reg, $xml, $matches)) {
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i++) {
                $subxml = $matches[2][$i];
                $key = $matches[1][$i];
                if (preg_match($reg, $subxml)) {
                    $arr[$key] = $this->xml_to_array($subxml);
                } else {
                    $arr[$key] = $subxml;
                }
            }
        }
        return $arr;
    }
}